#include "dameon.h"

unsigned int   http_show_help       = 0;
unsigned int   http_show_version    = 0;
unsigned int   http_show_configure  = 0;
unsigned int   http_test_config      = 0;
unsigned int   http_quiet_mode       = 0;
unsigned int   http_normal_mode     = 0;

unsigned char  *http_prefix;
unsigned char  *http_conf_file;
unsigned char  *http_conf_params;
char           *http_signal;

int              http_process_slot = 0;
int              http_last_process = 0;
http_channel_t   http_channel;
http_process_t   http_processes[HTTP_MAX_PROCESSES];

unsigned int      http_process;
pid_t             http_pid;
pid_t             http_new_binary;
unsigned int      http_inherited;
unsigned int      http_daemonized;
unsigned int      http_threaded;
unsigned int      http_exiting;

pid_t             new_binary;

sig_atomic_t    http_reap;
sig_atomic_t    http_sigio;
sig_atomic_t    http_sigalrm;
sig_atomic_t    http_quit;
sig_atomic_t    http_debug_quit;
sig_atomic_t    http_terminate;
sig_atomic_t    http_noaccept;
sig_atomic_t    http_reconfigure;
sig_atomic_t    http_reopen;
sig_atomic_t    http_change_binary;

int             http_channel_id;

volatile sig_atomic_t _running = 1;
const char *the_db_name;
 
//dameon.pid
int ProcessDameon()
{
	pid_t pc;
	int i;
	pc = fork();//第一步
	
	if (pc<0) {
	  printf("error fork\n");
	  exit(1);
	}
	else if(pc>0) {
	  exit(0);
	}
	
	setsid(); //第二步
	chdir("/"); //第三步
	umask(0); //第四步
	
	for(i=0;i<MAXFILE;i++) { //第五步
	  close(i);
	}
	
	return 0;
}

//work process
void ProcessCycle()
{
    Sock::CSock sock;
    vecStr ret;
    mapStrStr param;
    
    //save current pid
    int pid=getpid();		
    std::string pid_s = itos(pid);
    WriteLog(pid_s.c_str(), DAMEONPID, "O_TRUNC");

    // create socket
    sock.nsock_init(SERVER_PORT);
    sock.nsock_setopt(SOCKLOPT_SERVER, &param);
    sock.nsock_exec(ret);
    sock.nsock_close();     
}

void HttpdIsRun()
{
    std::string s;
    ReadFile(s, DAMEONPID);    
    int pid = stoi(s);
    if (pid && kill(pid, 0)>=0) {
        log( "process %d has been running!", pid ); 
        exit(0);
    }
    else {
        llog( "New process will be running! %d", getpid() );
    }
}

int initrun()
{
	file_open_log = fopen("/tmp/httpd.log", "a");	    			
	return 0;
}

int endrun()
{
    fclose(file_open_log);
    return 0;
}

int mainrun(int argc, char **argv, const char *dbname)
{      
    int         pid     = getpid();		
    std::string pid_s   = itos(pid);
    
    http_cycle_t  *cycle;
    the_db_name = dbname;
    
    initrun();
    
    try {
          
        //parse options 
        HttpdGetOptions(argc, argv);
        
        //show version?
        HttpdShowVersion();
        
        HttpdInitSignals();
        
        if (http_signal) {
            return HttpdSignalProcess(cycle, http_signal);
        }   
        
        //has been running?
        HttpdIsRun();        

        //start dameon process
        if (!http_normal_mode) {
            ProcessDameon();
        }

        //parse config
        readFile();   
        
        //start work   
        ProcessCycle();
        
    } 
    catch (CThrowException e) {
        //e.getMessage().c_str();
        llog( "Error: %s",  e.getMessage().c_str() );
        log( " %s",  e.getMessage().c_str() );
    }
    
    endrun();
            
    return 0;
}
